package com.fanyue.modules.wzb.controller.admin;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.fanyue.core.annotation.CoolRestController;
import com.fanyue.core.base.BaseController;
import com.fanyue.core.exception.CoolPreconditions;
import com.fanyue.core.file.FileUploadStrategyFactory;
import com.fanyue.core.request.R;
import com.fanyue.modules.base.entity.sys.BaseSysDepartmentEntity;
import com.fanyue.modules.base.service.sys.BaseSysDepartmentService;
import com.fanyue.modules.wzb.entity.AppUserEntity;
import com.fanyue.modules.wzb.entity.ClothingSpecEntity;
import com.fanyue.modules.wzb.mapper.ClothingSpecMapper;
import com.fanyue.modules.wzb.service.AppUserService;
import com.fanyue.modules.wzb.service.ClothingSpecService;
import com.fanyue.modules.wzb.utils.FaceApiUtils;
import com.fanyue.modules.wzb.vo.AppUserImportVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.checkerframework.checker.units.qual.K;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 人员信息
 */
@Tag(name = "人员信息", description = "人员信息")
@CoolRestController(api = { "add", "delete", "update", "page", "list", "info" })
@AllArgsConstructor
public class AppUserController extends BaseController<AppUserService, AppUserEntity> {

    private final FileUploadStrategyFactory fileUploadStrategyFactory;
    private final BaseSysDepartmentService sysDepartmentService;
    private final ClothingSpecService clothingSpecService;

    private static boolean faceListLock = false; //执行锁
    private static String filePath = "/data/data/service/api/assets/public";
    //private static String filePath = "D:\\workspace\\fanyue\\storehouse-wzb\\storehouse-wzb-api\\assets\\public";;
    private static String fileUrl = "http://192.168.1.10:8001";
    //private static String fileUrl = "http://127.0.0.1:8001";

    @Override
    protected void init(HttpServletRequest request, JSONObject requestParams) {
    }

    @Operation(summary = "人脸解析")
    @PostMapping("/analysisFace")
    public R analysisFace(@RequestAttribute JSONObject requestParams) {
        //保存人脸
        AppUserEntity appUser = service.getById(requestParams.getLong("userId"));
        CoolPreconditions.check(ObjectUtil.isEmpty(appUser), "用户信息错误");
        appUser.setHeadImage(requestParams.get("headImage").toString());
        //开始解析
        String fileName = requestParams.get("headImage").toString().replace(fileUrl, filePath);
        File file = new File(fileName);
        try {
            String result = FaceApiUtils.extract(appUser.getId(), file);
            JSONObject jsonObject = new JSONObject(result);
            Integer code = jsonObject.getInt("code");
            String msg = jsonObject.getStr("message");
            if (code != 200) {
                return R.error(msg);
            } else {
                service.updateById(appUser);
                return R.ok();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.ok();
    }


    @Operation(summary = "人脸解析")
    @GetMapping("/analysisFaceBatch")
    public R analysisFaceBatch() {
        //处理开关
        if (faceListLock) {
            return R.error("正在处理中,请稍后！！！");
        }
        faceListLock = true;

        AppUserEntity selectAppUser = new AppUserEntity();
        selectAppUser.setStatus(1);
        selectAppUser.setFaceId(0L);
        List<AppUserEntity> appUserList = service.listByInfo(selectAppUser);
        if(appUserList.size() == 0) {
            faceListLock = false;
            return R.error("无处理信息。");
        }

        //多线程处理
        ThreadUtil.execAsync(new Runnable() {
            @Override
            public void run() {
                for (AppUserEntity appUser: appUserList) {
                    String fileName = appUser.getHeadImage().replace(fileUrl, filePath);
                    File file = new File(fileName);
                    try {
                        FaceApiUtils.extract(appUser.getId(), file);
                    } catch (Exception e) {
                        faceListLock = false;
                        e.printStackTrace();
                    }
                }
                faceListLock = false;
            }
        });

        return R.ok();
    }

    @Operation(summary = "导入校验")
    @PostMapping("/importCheck")
    public R importCheck(
            @RequestParam("file") MultipartFile file,
            HttpServletRequest request
    ) {
        MultipartFile[] files = new MultipartFile[]{file};
        String url = String.valueOf(fileUploadStrategyFactory.upload(files, request));
        String fileName = url.replace(fileUrl, filePath);

        ExcelReader reader = ExcelUtil.getReader(fileName);
        List<Map<String, Object>> readAll = reader.read(1, 2, 1000000);
        List<AppUserImportVO> list = new ArrayList<>();

        List<BaseSysDepartmentEntity> departmentList = sysDepartmentService.allList();
        List<ClothingSpecEntity> specList = clothingSpecService.listByInfo(new ClothingSpecEntity());

        int index = 1;
        boolean fail = false;
        String failIndexs = "";
        String uidList = "";
        for (Map<String, Object> map: readAll) {
            AppUserImportVO appUserImportVO = new AppUserImportVO();
            appUserImportVO.setErrorMsg("");
            appUserImportVO.setStatus(1);
            appUserImportVO.setIndex(index);
            if (map.get("姓名") == null) {
                appUserImportVO.setName("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写姓名；"));
            } else {
                appUserImportVO.setName(map.get("姓名").toString());
            }
            if (map.get("身份证号") == null) {
                appUserImportVO.setUid("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写身份证号；"));
            } else {
                appUserImportVO.setUid(map.get("身份证号").toString());
                //查询系统是否重复
                if (uidList.contains(appUserImportVO.getUid())) {
                    appUserImportVO.setStatus(0);
                    appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("身份证号重复；"));
                } else {
                    AppUserEntity selectAppUser = new AppUserEntity();
                    selectAppUser.setUid(appUserImportVO.getUid());
                    List<AppUserEntity> userList = service.listByInfo(selectAppUser);
                    if (userList.size() > 0) {
                        appUserImportVO.setStatus(0);
                        appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("身份证号已存在；"));
                    }
                }
                uidList = uidList.concat(appUserImportVO.getUid());
            }
            if (map.get("手机号") == null) {
                appUserImportVO.setMobile("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写手机号；"));
            } else {
                appUserImportVO.setMobile(map.get("手机号").toString());
            }
            if (map.get("性别") == null) {
                appUserImportVO.setSex("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写性别；"));
            } else {
                appUserImportVO.setSex(map.get("性别").toString());
                if (!appUserImportVO.getSex().equals("男") && !appUserImportVO.getSex().equals("女")) {
                    appUserImportVO.setStatus(0);
                    appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("性别格式错误；"));
                }
            }
            if (map.get("编组(须按固定格式)") == null) {
                appUserImportVO.setDepartment("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写编组；"));
            } else {
                appUserImportVO.setDepartment(map.get("编组(须按固定格式)").toString());
                String[] departments = appUserImportVO.getDepartment().split("/");
                boolean isDept;
                for (int i = 0; i < departments.length; i++) {
                    if (i == 0) {
                        isDept = departmentCheck(departmentList, departments[i], "0");
                    } else {
                        isDept = departmentCheck(departmentList, departments[i], departments[i - 1]);
                    }
                    if (!isDept) {
                        appUserImportVO.setStatus(0);
                        appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("编组【" + departments[i] + "】错误；"));
                        break;
                    }
                }
            }
            if (map.get("作训帽型号") == null) {
                appUserImportVO.setSpec1("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写作训帽型号；"));
            } else {
                appUserImportVO.setSpec1(map.get("作训帽型号").toString());
                Long specId = specCheck(specList, appUserImportVO.getSpec1(), 1);
                if (specId.equals(-1L)) {
                    appUserImportVO.setStatus(0);
                    appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("作训帽型号错误；"));
                }
            }

            if (map.get("作训服型号") == null) {
                appUserImportVO.setSpec2("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写作训服型号；"));
            } else {
                appUserImportVO.setSpec2(map.get("作训服型号").toString());
                Long specId = specCheck(specList, appUserImportVO.getSpec2(), 2);
                if (specId.equals(-1L)) {
                    appUserImportVO.setStatus(0);
                    appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("作训服型号错误；"));
                }
            }

            if (map.get("体训服型号") == null) {
                appUserImportVO.setSpec3("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写体训服型号；"));
            } else {
                appUserImportVO.setSpec3(map.get("体训服型号").toString());
                Long specId = specCheck(specList, appUserImportVO.getSpec3(), 3);
                if (specId.equals(-1L)) {
                    appUserImportVO.setStatus(0);
                    appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("体训服型号错误；"));
                }
            }

            if (map.get("作战靴型号") == null) {
                appUserImportVO.setSpec4("");
                appUserImportVO.setStatus(0);
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("请填写作战靴型号；"));
            } else {
                appUserImportVO.setSpec4(map.get("作战靴型号").toString());
                Long specId = specCheck(specList, appUserImportVO.getSpec4(), 4);
                if (specId.equals(-1L)) {
                    appUserImportVO.setStatus(0);
                    appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().concat("作战靴型号错误；"));
                }
            }
            //去除最后“；”
            if (appUserImportVO.getErrorMsg().length() > 0) {
                appUserImportVO.setErrorMsg(appUserImportVO.getErrorMsg().substring(0, appUserImportVO.getErrorMsg().length() - 1));
            }
            list.add(appUserImportVO);
            if (appUserImportVO.getStatus() == 0) {
                fail = true;
                failIndexs = failIndexs.concat(String.valueOf(index)).concat("、");
            }
            index ++;
        }
        //去除最后“；”
        if (failIndexs.length() > 0) {
            failIndexs = failIndexs.substring(0, failIndexs.length() - 1);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("list", list);
        map.put("failIndexList", failIndexs);
        map.put("fail", fail);
        return R.ok(map);
    }

    @Operation(summary = "导入保存")
    @PostMapping("/importSave")
    public R importSave(@RequestAttribute JSONObject requestParams) {
        List<AppUserImportVO> importVOList = requestParams.getBeanList("list", AppUserImportVO.class);
        return service.importSave(importVOList);
    }

    private static boolean departmentCheck(
            List<BaseSysDepartmentEntity> departmentList,
            String name,
            String parentName) {
        BaseSysDepartmentEntity department = new BaseSysDepartmentEntity();
        Long pid = 0L;
        for (BaseSysDepartmentEntity departmentEntity: departmentList) {
            if (departmentEntity.getName().equals(name)) {
                department = departmentEntity;
            }
            if (departmentEntity.getName().equals(parentName)) {
                pid = departmentEntity.getId();
            }
        }
        if (ObjectUtil.isEmpty(department)) {
            return false; //不存在
        }
        if (!parentName.equals("0")) {
            return department.getParentId() != null && department.getParentId().equals(pid); //不存在
        }
        return true;
    }

    private static Long specCheck(
            List<ClothingSpecEntity> specList,
            String name,
            Integer category) {
        for (ClothingSpecEntity specEntity: specList) {
            if (specEntity.getCategory().equals(category) && specEntity.getName().equals(name)) {
                return specEntity.getId();
            }
        }
        return -1L;
    }
}